package com.gc.materialdesign.views;

import com.gc.materialdesign.utils.Utils;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

public class ProgressBarCircularIndeterminate extends CustomView {
    String backgroundColor = "#1E88E5FF";
    private Context context;

    public ProgressBarCircularIndeterminate(Context context) {
        this(context, null);
    }

    public ProgressBarCircularIndeterminate(Context context, AttrSet attrs) {
        this(context, attrs, null);
    }

    public ProgressBarCircularIndeterminate(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        setAttributes(attrs);
    }

    // Set atributtes of XML to View
    protected void setAttributes(AttrSet attrs) {
        setMinHeight(Utils.dpToPx(32, context));
        setMinWidth(Utils.dpToPx(32, context));

        boolean backgroundIsPresent = attrs.getAttr("background").isPresent();
        if (backgroundIsPresent) {
            String color = attrs.getAttr("background").get().getStringValue();
            setBackgroundColor(color);
        }

        setMinHeight(Utils.dpToPx(3, context));
    }

    /**
     * Make a dark color to ripple effect
     *
     * @return 改变后的颜色值
     */
    protected String makePressColorString() {
        int colorInt;
        if (backgroundColor.length() == 7) {
            colorInt = Color.getIntColor(backgroundColor);
        } else {
            colorInt = Color.getIntColor(backgroundColor.substring(0, backgroundColor.length() - 2));
        }
        int r = (colorInt >> 16) & 0xFF;
        int g = (colorInt >> 8) & 0xFF;
        int b = (colorInt >> 0) & 0xFF;
        StringBuilder builder =
                new StringBuilder("#")
                        .append(Integer.toHexString(128))
                        .append(colorPrefix(Integer.toHexString(r)))
                        .append(colorPrefix(Integer.toHexString(g)))
                        .append(colorPrefix(Integer.toHexString(b)));
        return builder.toString();
    }

    private String colorPrefix(String string) {
        return string.length() > 1 ? string : "00";
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        super.onDraw(component, canvas);
        if (!firstAnimationOver) {
            drawFirstAnimation(canvas);
        }
        if (cont > 0) {
            drawSecondAnimation(canvas);
        }
        getContext().getUITaskDispatcher().asyncDispatch(this::invalidate);
    }

    private float radius1 = 0;
    private float radius2 = 0;
    private int cont = 0;
    private boolean firstAnimationOver = false;

    /**
     * Draw first animation of view
     *
     * @param canvas
     */
    private void drawFirstAnimation(Canvas canvas) {
        if (radius1 < getWidth() / 2) {
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(new Color(Color.getIntColor(makePressColorString())));
            radius1 = (radius1 >= getWidth() / 2) ? (float) getWidth() / 2 : radius1 + 1;
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius1, paint);
        } else {
            PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
            initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
            initializationOptions.size = new Size(getWidth(), getHeight());
            PixelMap bitmap = PixelMap.create(initializationOptions);
            Texture texture = new Texture(bitmap);

            Canvas temp = new Canvas(texture);
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(new Color(Color.getIntColor(makePressColorString())));
            temp.drawCircle(getWidth() / 2, getHeight() / 2, getHeight() / 2, paint);
            Paint transparentPaint = new Paint();
            transparentPaint.setAntiAlias(true);
            transparentPaint.setColor(Color.TRANSPARENT);
            transparentPaint.setBlendMode(BlendMode.CLEAR);
            if (cont >= 50) {
                radius2 = (radius2 >= getWidth() / 2) ? (float) getWidth() / 2 : radius2 + 1;
            } else {
                radius2 =
                        (radius2 >= getWidth() / 2 - Utils.dpToPx(4, context))
                                ? (float) getWidth() / 2 - Utils.dpToPx(4, context)
                                : radius2 + 1;
            }
            temp.drawCircle(getWidth() / 2, getHeight() / 2, radius2, transparentPaint);
            canvas.drawPixelMapHolder(new PixelMapHolder(bitmap), 0, 0, new Paint());
            if (radius2 >= getWidth() / 2 - Utils.dpToPx(4, context)) {
                cont++;
            }
            if (radius2 >= getWidth() / 2) {
                firstAnimationOver = true;
            }
        }
    }

    private int arcD = 1;
    private int arcO = 0;
    private float rotateAngle = 0;
    private int limite = 0;

    /**
     * Draw second animation of view
     *
     * @param canvas
     */
    private void drawSecondAnimation(Canvas canvas) {
        if (arcO == limite) arcD += 6;
        if (arcD >= 290 || arcO > limite) {
            arcO += 6;
            arcD -= 6;
        }
        if (arcO > limite + 290) {
            limite = arcO;
            arcO = limite;
            arcD = 1;
        }
        rotateAngle += 4;
        canvas.rotate(rotateAngle, getWidth() / 2, getHeight() / 2);

        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
        initializationOptions.size = new Size(getWidth(), getHeight());
        PixelMap bitmap = PixelMap.create(initializationOptions);
        Texture texture = new Texture(bitmap);

        Canvas temp = new Canvas(texture);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(new Color(Color.getIntColor(Utils.argb(backgroundColor))));
        RectFloat rectFloat = new RectFloat(0, 0, getWidth(), getHeight());
        Arc arc = new Arc(arcO, arcD, true);
        temp.drawArc(rectFloat, arc, paint);
        Paint transparentPaint = new Paint();
        transparentPaint.setAntiAlias(true);
        transparentPaint.setColor(Color.TRANSPARENT);
        transparentPaint.setBlendMode(BlendMode.CLEAR);
        temp.drawCircle(getWidth() / 2, getHeight() / 2, (getWidth() / 2) - Utils.dpToPx(4, context), transparentPaint);

        canvas.drawPixelMapHolder(new PixelMapHolder(bitmap), 0, 0, new Paint());
    }

    // Set color of background
    public void setBackgroundColor(String rgba) {
        if (isEnabled()) {
            beforeBackground = backgroundColor;
        }
        this.backgroundColor = rgba;
    }
}
